package com.gitee.qdbp.vmall.sales.api.goods.main.service;

import com.gitee.qdbp.able.exception.ServiceException;
import com.gitee.qdbp.able.model.reusable.EditResult;
import com.gitee.qdbp.base.system.model.IAccount;
import com.gitee.qdbp.vmall.sales.api.goods.main.model.GoodsVersionBean;
import com.gitee.qdbp.vmall.sales.api.goods.main.model.PriceSingleParams;
import com.gitee.qdbp.vmall.sales.api.goods.main.model.PublishSingleParams;
import com.gitee.qdbp.vmall.sales.api.goods.main.model.QuantitySingleParams;

/**
 * 商品版本信息业务接口<br>
 * 目前的实现方式: 商品允许存在多份未发布的副本, 但只允许一份正本;<br>
 * 商品发布就是将副本发布为正本, 原正本变成历史版本; 发布时如果存在多份副本就需要选择一份, 批量发布时自动选择最新的一份.<br>
 * 编辑一个商品时, 先列出所有正本和副本: 对正本,已提交的副本不允许直接编辑, 只允许"创建副本并编辑";<br>
 * 对未提交(草稿)或被驳回的副本, 可以"编辑"和"删除"<br>
 * <br>
 * 版本冲突:<br>
 * 商品版本是指商品发布版本, 编辑版本是指editIndex<br>
 * 商品副本每编辑保存一次editIndex加1, 保存时如果版本冲突将报错<br>
 * 场景: 用户张三查询到商品A规格300g(编辑版本=5); <br>
 * 用户李四查询到商品A规格300g(编辑版本=5), 修改为320g并保存(编辑版本变更为6);<br>
 * 张三仍停留在编辑版本5的界面, 此时他修改为310g并保存就会报错'记录在提交前已被编辑'.<br>
 *
 * @author zhh
 * @version 180627
 */
public interface IGoodsVersionExecutor {

    /** 创建副本 **/
    GoodsVersionBean createDuplicate(String goodsVid, IAccount me) throws ServiceException;

    /** 保存 **/
    EditResult save(GoodsVersionBean model, IAccount me) throws ServiceException;

    /** 提交审核 **/
    void submit(GoodsVersionBean model, String description, IAccount me) throws ServiceException;

    /** 审批 **/
    void approve(String goodsVid, boolean pass, String description, IAccount me) throws ServiceException;

    /** 发布上架(只允许发布已审核或已下架的)(如果是已下架版本重新发布且价格有调整, 则自动生成新的副本并发布上架) **/
    EditResult publish(PublishSingleParams params, IAccount me) throws ServiceException;

    /** 下架停售 **/
    void unpublish(String goodsVid, String description, IAccount me) throws ServiceException;

    /** 删除商品(从未发布上架过的直接删除, 曾经发布上架过的不能删除,只将版本状态改为ENDED) **/
    void delete(String goodsVid, String description, IAccount me) throws ServiceException;

    /** 补充库存 **/
    void updateStockQuantity(QuantitySingleParams params, IAccount me) throws ServiceException;

    /** 调整销量 **/
    void updateSalesQuantity(QuantitySingleParams params, IAccount me) throws ServiceException;

    /** 修改价格(只允许修改未发布上架的商品) **/
    EditResult editPrice(PriceSingleParams params, IAccount me) throws ServiceException;

    /** 调整价格(已发布上架的商品, 自动生成新的副本并直接发布上架) **/
    EditResult changePrice(PriceSingleParams params, IAccount me) throws ServiceException;
}
